<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Shop\Controller;

use Admin\Data\Common;
use Doctrine\ORM\EntityManager;
use Goods\Entity\Goods;
use Goods\Entity\GoodsAttribute;
use Goods\Entity\GoodsAttributeValue;
use Goods\Entity\GoodsClass;
use Goods\Entity\GoodsCommonContent;
use Goods\Entity\GoodsConsultation;
use Goods\Entity\GoodsCustom;
use Goods\Entity\GoodsImage;
use Goods\Entity\GoodsInAttribute;
use Goods\Entity\GoodsInClass;
use Goods\Entity\GoodsInSpecGoods;
use Goods\Entity\GoodsInSpecGroupTag;
use Goods\Entity\GoodsInSpecImage;
use Goods\Entity\GoodsInWholesale;
use Goods\Service\GoodsConsultationManager;
use Goods\Service\GoodsManager;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
use Operation\Entity\UserCoupon;
use Operation\Service\Common\Coupon;
use Operation\Service\UserCouponManager;
use Sales\Entity\OrderGoodsEvaluation;
use Shop\Form\GoodsConsultationForm;
use User\Entity\UserGoodsFavorites;
use User\Service\UserGoodsFavoritesManager;

class GoodsController extends AbstractActionController
{
    private $translator;
    private $entityManager;
    private $goodsConsultationManager;
    private $userGoodsFavoritesManager;
    private $goodsManager;
    private $userCouponManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        GoodsConsultationManager $goodsConsultationManager,
        UserGoodsFavoritesManager $userGoodsFavoritesManager,
        GoodsManager $goodsManager,
        UserCouponManager $userCouponManager
    )
    {
        $this->translator   = $translator;
        $this->entityManager= $entityManager;
        $this->goodsConsultationManager = $goodsConsultationManager;
        $this->userGoodsFavoritesManager= $userGoodsFavoritesManager;
        $this->goodsManager = $goodsManager;
        $this->userCouponManager = $userCouponManager;
    }

    /**
     * 商品详情
     * @return array|\Laminas\Http\Response|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $goodsId        = (int) $this->params()->fromRoute('id', 0);
        $inClassId      = (int) $this->params()->fromQuery('classId', 0);//当前的分类
        $specTagIdStr   = $this->params()->fromQuery('tId', '');

        if($goodsId <= 0) return $this->redirect()->toRoute('shop');

        $goodsInfo = $this->entityManager->getRepository(Goods::class)->findShopGoodsInfo($goodsId);
        if($goodsInfo == null || ($goodsInfo && $goodsInfo[0]->getClassId() <= 0)) return $this->redirect()->toRoute('shop');
        $classId   = $goodsInfo[0]->getClassId();//商品主分类id

        //检查当前分类是在商品中
        if ($inClassId <= 0) $inClassId = $classId;
        $goodsInClass = $this->entityManager->getRepository(GoodsInClass::class)->findOneBy(['goodsId' => $goodsId, 'classId' => $inClassId]);
        if ($goodsInClass == null)  return $this->redirect()->toRoute('shop');
        $inClassInfo = $this->entityManager->getRepository(GoodsClass::class)->findOneBy(['classId' => $inClassId, 'classState' => 1]);

        $this->layout()->setVariables([
            'titleName'         => $goodsInfo[0]->getGoodsName(),
            'extendTitleName'   => $goodsInfo[0]->getGoodsExtendName(),
            'extendKeywords'    => $goodsInfo[0]->getGoodsKeywords(),
            'extendDescription' => $goodsInfo[0]->getGoodsDescription()
        ]);

        //如果有带规格的请求
        $specImages = null;
        $specGoodsInfo = null;
        $specTagIdArray= null;
        if(!empty($specTagIdStr)) {
            $specTagIdArray = array_filter(explode(',', $specTagIdStr), function ($value) { return (int) $value; });
            sort($specTagIdArray);
            $specGoodsInfo = $this->entityManager->getRepository(GoodsInSpecGoods::class)->findOneBy(['specTagId' => implode('-', $specTagIdArray), 'goodsId' => $goodsId]);
            if($specGoodsInfo == null) return $this->redirect()->toRoute('shop-goods', ['id' => $goodsId]);

            $specGoodsImageType = $this->entityManager->getRepository(GoodsInSpecGroupTag::class)->findOneBy(['goodsId' => $goodsId, 'groupImage' => 1]);
            if($specGoodsImageType && !empty($specGoodsImageType->getSelectedTagId())) {//存在规格商品图片
                $imageTagId = explode(',', $specGoodsImageType->getSelectedTagId());
                $tagId = current(array_intersect($imageTagId, $specTagIdArray));//获取交集
                if ($tagId > 0) {
                    $specImages = $this->entityManager->getRepository(GoodsInSpecImage::class)->findGoodsSpecImageList($tagId, $goodsId);
                }
            }
        }

        //商品图片
        $goodsImages = null;
        if($specImages == null) $goodsImages = $this->entityManager->getRepository(GoodsImage::class)->findBy(['goodsId' => $goodsId, 'imageSlide' => 1], ['imageSort' => 'ASC']);

        //客户组
        $userGroup = $this->userPlugin()->userGroupOptions('', false);

        //商品自定义
        $goodsCustom = $this->entityManager->getRepository(GoodsCustom::class)->findBy(['goodsId' => $goodsId, 'frontShow' => 1], ['customKey' => 'ASC']);

        //商品规格
        $goodsSpec = $this->entityManager->getRepository(GoodsInSpecGroupTag::class)->findShopGoodsSpecGroupTag($goodsId);

        //商品属性
        $goodsAttribute = $this->getGoodsAttribute($goodsInfo[0]->getAttributeGroupid(), $goodsId);

        //商品通用内容
        $goodsCommonContent = $this->entityManager->getRepository(GoodsCommonContent::class)->findGoodsCommonContent($classId);

        //商品批发价格
        $goodsWholesaleList = null;
        if($goodsInfo[0]->getWholesaleState() == 1) {
            $goodsWholesaleList = $this->entityManager->getRepository(GoodsInWholesale::class)->findBy(['goodsId' => $goodsId], ['wholesaleKey' => 'ASC']);
        }

        //优惠价格,满足条件时，才会起作用
        if ($goodsInfo['discountPrice'] > 0) {
            if (!Common::checkTime($goodsInfo['discountStartTime'], $goodsInfo['discountEndTime']) || !Common::checkUser($this->shopPlugin()->getUserLoginData('user_group_id'), $goodsInfo['discountUserGroupType'], unserialize($goodsInfo['discountUserGroup']))) $goodsInfo['discountPrice'] = 0.00;
        }

        $response = $this->getEventManager()->trigger('shop.goodsInfo.goods.show', $this, ['goodsInfo' => $goodsInfo]);

        //更新商品点击查看
        $this->goodsManager->updateGoodsClick($goodsId);

        //咨询表单
        $consultForm    = new GoodsConsultationForm();
        $consultForm->setData(['consultGoodsId' => $goodsId]);

        $goodsPartial = $this->shopPlugin()->shopPartial('goods');

        return [
            'classId'       => $classId,//主分类
            'inClassInfo'   => $inClassInfo,//当前的分类
            'goodsInfo'     => $goodsInfo,
            'goodsImages'   => $goodsImages,
            'userGroup'     => $userGroup,
            'goodsCustom'   => $goodsCustom,
            'goodsSpec'     => $goodsSpec,
            'goodsAttribute'=> $goodsAttribute,
            'consultForm'   => $consultForm,
            'goodsCommonContent' => $goodsCommonContent,

            'goodsWholesaleList' => $goodsWholesaleList,
            'specGoodsInfo' => $specGoodsInfo,
            'specImages'    => $specImages,
            'selectedSpecTagId' => $specTagIdArray,

            'goodsPartial'  => $goodsPartial,
            'showData'      => $response->last()
        ];
    }

    /**
     * 商品分享
     * @return array|\Laminas\Http\Response
     */
    public function goodsShareAction()
    {
        $goodsId        = (int) $this->params()->fromRoute('id', 0);

        if($goodsId <= 0) return $this->redirect()->toRoute('shop');

        $goodsInfo = $this->entityManager->getRepository(Goods::class)->findShopGoodsInfo($goodsId);
        if($goodsInfo == null || ($goodsInfo && $goodsInfo[0]->getClassId() <= 0)) return $this->redirect()->toRoute('shop');

        $goodsQrCodeImage = $this->shopPlugin()->shopGoodsShareQrCodeImage($goodsInfo);

        return ['goodsInfo' => $goodsInfo, 'goodsQrCodeImage' => $goodsQrCodeImage];
    }

    /**
     * 规格商品获取
     * @return JsonModel
     */
    public function specTagGoodsInfoAction()
    {
        $goodsId        = (int) $this->params()->fromRoute('id', 0);
        $specTagIdStr   = $this->params()->fromPost('specTagIdStr', '');

        if($goodsId <= 0 || empty($specTagIdStr)) return new JsonModel(['status' => 'false']);

        $specTagIdArray = array_filter(explode(',', $specTagIdStr), function ($value) { return (int) $value; });
        sort($specTagIdArray);
        $specTagGoods = $this->entityManager->getRepository(GoodsInSpecGoods::class)->findOneBy(['specTagId' => implode('-', $specTagIdArray), 'goodsId' => $goodsId]);
        if($specTagGoods == null) return new JsonModel(['status' => 'false']);

        $specImageArray     = [];
        $specGoodsImageType = $this->entityManager->getRepository(GoodsInSpecGroupTag::class)->findOneBy(['goodsId' => $goodsId, 'groupImage' => 1]);
        if($specGoodsImageType && !empty($specGoodsImageType->getSelectedTagId())) {//存在规格商品图片
            $imageTagId = explode(',', $specGoodsImageType->getSelectedTagId());
            $tagId      = current(array_intersect($imageTagId, $specTagIdArray));//获取交集
            if($tagId > 0) {
                $specImageList = $this->entityManager->getRepository(GoodsInSpecImage::class)->findGoodsSpecImageList($tagId, $goodsId);
                if($specImageList) {
                    foreach ($specImageList as $imageValue) {
                        $specImageArray[] = [
                            'goodsThumbnailImage' => substr($imageValue['goodsThumbnailImage'],0, 4) == 'http' ? $imageValue['goodsThumbnailImage'] : $this->request->getBasePath() . '/' . $imageValue['goodsThumbnailImage'],
                            'goodsImage' => substr($imageValue['goodsImage'],0, 4) == 'http' ? $imageValue['goodsImage'] : $this->request->getBasePath() . '/' . $imageValue['goodsImage']
                        ];
                    }
                }
            }
        }

        return new JsonModel([
            'status' => 'true',
            'item'  => $specTagGoods->getSpecGoodsItem(),
            'stock' => $specTagGoods->getSpecGoodsStock(),
            'price' => $specTagGoods->getSpecGoodsPrice(),
            'specImage' => $specImageArray
        ]);
    }
    /**
     * 添加商品咨询
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addGoodsConsultAction()
    {
        $array = ['status' => 'false', 'message' => $this->translator->translate('商品咨询添加失败!')];

        $form = new GoodsConsultationForm();
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data['goodsId'] = $data['consultGoodsId']; unset($data['consultGoodsId']);
                $goodsInfo = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $data['goodsId'], 'goodsState' => 1]);
                if($goodsInfo) {
                    $data['consultUser'] = '游客';
                    $this->goodsConsultationManager->addGoodsConsultation($data);
                    $array['status'] = 'true';
                } else $array['message'] = $this->translator->translate('该商品不存在!');
            } else {
                $errorMessages = $form->getMessages();
                if (isset($errorMessages['consultContent'])) $array['message'] = $this->translator->translate('咨询内容不能为空!');
                if (isset($errorMessages['consultCaptcha'])) $array['message'] = $this->translator->translate('验证码错误，请重新填写!');
                if (isset($errorMessages['shopCsrf'])) $array['message'] = $this->translator->translate('超时请求，请刷新当前页面后，再次提交!');
            }
        }

        return new JsonModel($array);
    }

    /**
     * 商品咨询列表
     * @return array|mixed
     */
    public function goodsConsultListAction()
    {
        $goodsId    = (int) $this->params()->fromRoute('id', 0);
        $goodsInfo  = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $goodsId, 'goodsState' => 1]);
        if($goodsInfo == null) return $this->response->setContent('');

        $view = new ViewModel();
        $view->setTerminal(true);

        $page = (int) $this->params()->fromQuery('page', 1);
        $query= $this->entityManager->getRepository(GoodsConsultation::class)->findShopGoodsConsultList($goodsId);
        $paginator = $this->shopPlugin()->shopPaginator($query, $page);

        return $view->setVariables(['consultList' => $paginator, 'goodsInfo' => $goodsInfo]);
    }

    /**
     * 商品评价列表
     * @return array|mixed
     */
    public function goodsEvaluationListAction()
    {
        $goodsId    = (int) $this->params()->fromRoute('id', 0);
        $goodsInfo  = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $goodsId, 'goodsState' => 1]);
        if($goodsInfo == null) return $this->response->setContent('');

        $view = new ViewModel();
        $view->setTerminal(true);

        $page = (int) $this->params()->fromQuery('page', 1);
        $query= $this->entityManager->getRepository(OrderGoodsEvaluation::class)->findShopGoodsEvaluationList($goodsId);
        $paginator = $this->shopPlugin()->shopPaginator($query, $page);

        return $view->setVariables(['evaluationList' => $paginator, 'goodsInfo' => $goodsInfo]);
    }

    /**
     * 收藏商品处理
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addGoodsFavoritesAction()
    {
        //判断是否登录
        if(!$this->shopPlugin()->checkUserLoginStatus()) return new JsonModel(['status' => 'false', 'message' => $this->translator->translate('请先登录，再收藏商品!')]);

        $goodsId    = (int) $this->params()->fromRoute('id', 0);

        $goodsInfo  = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $goodsId, 'goodsState' => 1]);
        if($goodsInfo == null) return new JsonModel(['status' => 'false', 'message' => $this->translator->translate('该商品不存在或已经下架，无法进行收藏!')]);

        $userId = $this->shopPlugin()->getUserLoginData('user_id');
        $goodsFavorites = $this->entityManager->getRepository(UserGoodsFavorites::class)->findOneBy(['goodsId' => $goodsId, 'userId' => $userId]);
        if($goodsFavorites) {
            $this->userGoodsFavoritesManager->deleteUserGoodsFavorites($goodsFavorites->getGoodsFavoritesId(), $userId);
            return new JsonModel(['status' => 'true', 'favoritesState' => 'remove', 'message' => $this->translator->translate('取消收藏!')]);
        }

        $this->userGoodsFavoritesManager->addUserGoodsFavorites(['goodsId' => $goodsId, 'userId'  => $userId]);
        return new JsonModel(['status' => 'true', 'favoritesState' => 'add', 'message' => $this->translator->translate('商品收藏完成!')]);
    }

    /**
     * 显示可领取的优惠券
     * @return array|mixed
     */
    public function clickGoodsCouponAction()
    {
        $goodsId    = (int) $this->params()->fromRoute('id', 0);
        $goodsInfo  = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $goodsId, 'goodsState' => 1]);
        if($goodsInfo == null) return $this->response->setContent('');

        $userGroupId    = $this->shopPlugin()->getUserLoginData('user_group_id');
        $couponIdArray  = Coupon::clickCouponList(['userGroupId' => $userGroupId, 'classId' => $goodsInfo->getClassId(), 'brandId' => $goodsInfo->getBrandId()], true);
        $couponList = '';
        if (!empty($couponIdArray)) $couponList = $this->entityManager->getRepository(\Operation\Entity\Coupon::class)->shopClickCouponList($couponIdArray, intval($this->shopPlugin()->getUserLoginData('user_id')));

        return ['couponList' => $couponList, 'goodsInfo' => $goodsInfo];
    }

    /**
     * 领取优惠券
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function clickGetCouponAction()
    {
        $userGroupId= $this->shopPlugin()->getUserLoginData('user_group_id');
        $userId     = $this->shopPlugin()->getUserLoginData('user_id');
        if ($userGroupId <= 0) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('登录后，才可以进行领取')]);

        $goodsId    = (int) $this->params()->fromPost('goodsId');
        $couponId   = (int) $this->params()->fromPost('couponId');
        $couponInfo = $this->entityManager->getRepository(\Operation\Entity\Coupon::class)->findOneBy(['couponId' => $couponId, 'getCouponType' => 'click', 'couponState' => 1]);
        if ($couponInfo) {
            $goodsInfo = $this->entityManager->getRepository(Goods::class)->findOneBy(['goodsId' => $goodsId, 'goodsState' => 1]);
            if (!Common::checkTime($couponInfo->getGetCouponStartTime(), $couponInfo->getGetCouponEndTime())) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('不在获取时间内，无法获取')]);
            if (!Common::checkUser($userGroupId, $couponInfo->getGetUserType(), Common::configValue($couponId, 'coupon')['userGroup'])) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('您所在等级没有领取权限')]);
            if (!Common::checkGoods($goodsInfo->getClassId(), $couponInfo->getGetGoodsType(), Common::configValue($couponId, 'coupon')['goodsBody'], $goodsInfo->getBrandId())) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('无法领取该优惠券')]);

            $userCoupon = $this->entityManager->getRepository(UserCoupon::class)->findOneBy(['userId' => $userId, 'couponId' => $couponId]);
            if ($userCoupon) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('您已经领取过该优惠券，不能重复领取')]);

            $this->userCouponManager->addUserCoupon([
                'couponUseState' => 1,
                'userId'        => $userId,
                'userName'      => $this->shopPlugin()->getUserLoginData('user_name'),
                'getTime'       => time(),
                'couponId'      => $couponId,
                'couponTitle'   => $couponInfo->getCouponTitle(),
                'couponInfo'    => $couponInfo->getCouponInfo(),
                'couponUseStartTime'=> $couponInfo->getCouponStartTime(),
                'couponUseEndTime'  => $couponInfo->getCouponEndTime()
            ]);
            return new JsonModel(['state' => 'true', 'message' => $this->translator->translate('领取成功')]);
        }
        return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('该优惠券不存在')]);
    }

    /**
     * 获取和解析商品属性
     * @param $attributeGroupId
     * @param $goodsId
     * @return array|null
     */
    private function getGoodsAttribute($attributeGroupId, $goodsId)
    {
        if($attributeGroupId <= 0) return null;

        $attribute      = $this->entityManager->getRepository(GoodsAttribute::class)->findBy(['attributeGroupId' => $attributeGroupId], ['attributeSort' => 'ASC']);
        $attributeValue = $this->entityManager->getRepository(GoodsAttributeValue::class)->findBy(['attributeGroupId' => $attributeGroupId], ['valueSort' => 'ASC']);
        $goodsAttribute = $this->entityManager->getRepository(GoodsInAttribute::class)->findBy(['goodsId' => $goodsId]);

        $valueArray     = [];
        if($attributeValue) foreach ($attributeValue as $vValue) {
            $valueArray[$vValue->getAttributeId()][$vValue->getValueId()] = $vValue->getValueName();
        }

        $goodsInAttribute= [];
        if($goodsAttribute) foreach ($goodsAttribute as $aValue) {
            $goodsInAttribute[$aValue->getAttributeId()] = $aValue->getAttributeBody();
        }

        $array = [];
        if($attribute) foreach ($attribute as $attrValue) {
            if(isset($goodsInAttribute[$attrValue->getAttributeId()]) && !empty($goodsInAttribute[$attrValue->getAttributeId()])) {
                switch ($attrValue->getAttributeType()) {
                    case 'select':
                    case 'radio':
                        $array[] = '<strong>' . $attrValue->getAttributeName() . '：</strong>' . $valueArray[$attrValue->getAttributeId()][$goodsInAttribute[$attrValue->getAttributeId()]];
                        break;

                    case 'checkbox':
                        $checkboxChecked = explode(',', $goodsInAttribute[$attrValue->getAttributeId()]);
                        $checkboxValueStr= '';
                        foreach ($checkboxChecked as $checkedId) {
                            $checkboxValueStr .= $valueArray[$attrValue->getAttributeId()][$checkedId] . ',';
                        }
                        $array[] = '<strong>' . $attrValue->getAttributeName() . '：</strong>' . rtrim($checkboxValueStr, ',');
                        break;

                    case 'input':
                    case 'textarea':
                        $array[] = '<strong>' . $attrValue->getAttributeName() . '：</strong>' . $goodsInAttribute[$attrValue->getAttributeId()];
                        break;
                }
            }
        }

        return $array;
    }
}